package object

import (
	"github.com/julienschmidt/httprouter"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"xj.com/oos-naming-service/config"
	"xj.com/oos-naming-service/error_handler"
	"xj.com/oos-naming-service/service/node"
	"xj.com/oos-naming-service/service/object"
	"xj.com/oos-naming-service/utils"
)

const (
	objectIdHeader = "X-Object-Id"
)

type ObjectController struct {
	objectService *object.ObjectService
	nodeService   *node.NodeService
}

type SubmitResult struct {
	Success bool
	Body    string
}

type MetaData struct {
}

func New() (s *ObjectController) {
	s = new(ObjectController)
	s.objectService = object.New()
	s.nodeService = node.New()
	return s
}

func (s *ObjectController) Get(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
	objectId := s.getObjectId(request)
	objectContent := s.objectService.Get(objectId)
	_, _ = writer.Write(objectContent)
}

func (s *ObjectController) Put(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	objectId := s.getObjectId(r)
	all, err := ioutil.ReadAll(r.Body)
	error_handler.HttpPanicIfError(errors.WithStack(err))

	if len(all) == 0 {
		error_handler.HttpPanicIfError(errors.New("对像的Payload不能为空。"))
	}
	nodes := s.nodeService.GetHealthyNodes()

	resultChan := make(chan SubmitResult, len(nodes))

	for _, node := range nodes {
		go func() {
			log.Debug("写入数据节点：", node.Ip)

			resp, err := utils.GetRestRequest().SetBody(all).SetHeader(objectIdHeader, objectId).Put(node.Ip + "/objects/")
			error_handler.HttpPanicIfError(err, "往数据节点写入数据出错。")

			result := SubmitResult{}
			result.Body = string(resp.Body())

			if err != nil {
				log.Error("往数据节点写入数据出错。")
				log.Error(err)
				log.Error(string(resp.Body()))
				result.Success = false
			} else {
				result.Success = true
			}

			resultChan <- result
		}()
	}
	resultList := make([]SubmitResult, len(nodes))
	for i := 0; i < len(nodes); i++ {
		resultList[i] = <-resultChan
	}

	go func() {
		esData := MetaData{}
		utils.GetRestRequest().SetBody(esData).Post(config.Config.Es.Url)
	}()

	w.WriteHeader(http.StatusOK)
}

func (s *ObjectController) getObjectId(r *http.Request) string {
	objectId := r.Header.Get(objectIdHeader)
	if len(objectId) == 0 {
		error_handler.HttpPanicIfError(errors.New(objectIdHeader + "不能为空。"))
	}

	return objectId
}
